/**
 * BusinessDataChrome namespace.
 */
if ("undefined" == typeof(BusinessDataChrome)) {
  var BusinessDataChrome = {};
};

/**
 * Controls the browser overlay for the Hello World extension.
 */
BusinessDataChrome.BrowserOverlay = {
  /**
   * Says 'Hello' to the user.
   */
  openPreferences : function(aEvent) {
    window.open("chrome://BusinessData/content/PreferencesWindow.xul", "", "chrome=yes,modal=yes");
  }
};
BusinessDataChrome.createTableScripts = [
    "CREATE TABLE bd_hosts (hostname text not null, accessKey text not null, secretKey text not null)"
]
BusinessDataChrome.accessInfo = null;


BusinessDataChrome.formatDate=function(dt){
    
}

BusinessDataChrome.createStringToSign = function(httpChannel,accessInfo, dt){
  var sts = httpChannel.requestMethod +'\n';
  // alert(sts);
  sts+=httpChannel.getRequestHeader('host')+'\n';
  var uri = httpChannel.URI.path;
  if (uri.indexOf('#') != -1){
    uri = uri.substring(0, uri.indexOf('#'));
  }
  sts += uri+'\n';
  sts += dt.toUTCString()+'\n';
  sts +=accessInfo.accessKey+'\n';
  sts +=httpChannel.getRequestHeader('Accept')+'\n';
  if (BusinessDataChrome.addGeneratedContext){
    var ctx = dt.getTime();
    sts += ctx +'\n'; 
  }
 // alert(sts);
 //BusinessDataChrome.console.logStringMessage("Source:");
 BusinessDataChrome.console.logStringMessage(sts);
 //BusinessDataChrome.console.logStringMessage("Length: "+sts.length);
  return sts;  
  
}
BusinessDataChrome.console = Components.classes["@mozilla.org/consoleservice;1"].
     getService(Components.interfaces.nsIConsoleService);




BusinessDataChrome.getLocalDirectory = function() {
	  let directoryService =
	    Cc["@mozilla.org/file/directory_service;1"].
	      getService(Ci.nsIProperties);
	  // this is a reference to the profile dir (ProfD) now.
	  let localDir = directoryService.get("ProfD", Ci.nsIFile);
	 
	  localDir.append("BusinessData");
	 
	  if (!localDir.exists() || !localDir.isDirectory()) {
	    // read and write permissions to owner and group, read-only for others.
	    localDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0774);
	  }
	 
	  return localDir;
};

BusinessDataChrome.openRequesterTab = function(){
    var myUrl = "chrome://businessdata/content/index.html";
    var tBrowser = top.document.getElementById("content");
    var tab = tBrowser.addTab(myUrl);
    // use this line to focus the new tab, otherwise it will open in background
    tBrowser.selectedTab = tab;
   // alert(tBrowser.contentWindow.content.document._content);
  //  tBrowser.contentWindow.content.document.BusinessDataChrome = new XPCNativeWrapper(BusinessDataChrome);
  //  window.close();
}
BusinessDataChrome.getStorageService= function(){
    var storageService = Components.classes["@mozilla.org/storage/service;1"].getService(Components.interfaces.mozIStorageService);
    return storageService;
}

BusinessDataChrome.getDataBaseConnection= function(){
    var localDir = BusinessDataChrome.getLocalDirectory();
    localDir.append("businessdata.sqlite");
    var db =  BusinessDataChrome.getStorageService().openDatabase(localDir);
    BusinessDataChrome.checkDBInitialized(db);
    return db;
}

BusinessDataChrome.checkDBInitialized= function(db){
    if (!db.tableExists('bd_hosts')){
        for( var dbi = 0;dbi < BusinessDataChrome.createTableScripts.length; dbi++){
            db.executeSimpleSQL(BusinessDataChrome.createTableScripts[dbi]);
        }
    }
}
BusinessDataChrome.setHostInfo=function(db, host, accessKey, secretKey){
    var insertStmt = "insert or replace into bd_hosts values (:host, :accessKey, :secretKey)";
    var stmt = db.createStatement(insertStmt);
    stmt.params.host = host;
    stmt.params.accessKey = accessKey;
    stmt.params.secretKey = secretKey;
    stmt.execute();
    BusinessDataChrome.accessInfo = null;
}

BusinessDataChrome.getHostInfo=function(db){
    var insertStmt = "select * from bd_hosts order by hostname asc";
    var stmt = db.createStatement(insertStmt);
    return stmt;
}
BusinessDataChrome.deleteHostInfo=function(db, host){
    var insertStmt = "delete from bd_hosts where hostname=:host";
    var stmt = db.createStatement(insertStmt);
    stmt.params.host = host;
    stmt.execute();
    BusinessDataChrome.accessInfo = null;

}
BusinessDataChrome.addJsonHeader = false;
BusinessDataChrome.addGeneratedContext = false;
BusinessDataChrome.enabled = false;
BusinessDataChrome.forceSaveDialog = false;
BusinessDataChrome.initAccessInfo = function(){
    if (BusinessDataChrome.accessInfo == null){
        var stmt = BusinessDataChrome.getHostInfo(BusinessDataChrome.getDataBaseConnection());
        BusinessDataChrome.accessInfo = {};
        while(stmt.executeStep()){
            
          BusinessDataChrome.accessInfo[stmt.row.hostname] = {accessKey:stmt.row.accessKey,secretKey:stmt.row.secretKey,host:stmt.row.hostname};  
        }
    }
}
BusinessDataChrome.getAccessInfoForHost = function(host){
    BusinessDataChrome.initAccessInfo();
    var info = BusinessDataChrome.accessInfo[host];
    if (info != null){
        
        return info;
    } 
    for (key in BusinessDataChrome.accessInfo){
        if (host.match(new RegExp("^"+key))){
           return BusinessDataChrome.accessInfo[key]; 
        }
    } 
    return BusinessDataChrome.accessInfo[host];
}

BusinessDataChrome.createSignature = function(secretKey, stringToSign){
    var hmacBytes = Crypto.HMAC(Crypto.SHA256, stringToSign, secretKey, { asBytes: true });
    return Crypto.util.bytesToBase64(hmacBytes)
}

//_businessData = XPCNativeWrapper.unwrap(BusinessDataChrome);

	let testObserver = {
	  observe : function(aSubject, aTopic, aData) {
	    if (BusinessDataChrome.enabled ){
	    var httpChannel = aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
	    var accessInfo = BusinessDataChrome.getAccessInfoForHost(httpChannel.getRequestHeader('host')); 
        if (accessInfo != null){
        if (aTopic == 'http-on-examine-response'){
            httpChannel.setResponseHeader('Access-Control-Allow-Origin','chrome://businessdata',false);
            if (BusinessDataChrome.forceSaveDialog && httpChannel.requestSucceeded){ 
                httpChannel.setResponseHeader('Content-disposition' ,'attachment; filename=response.'+(BusinessDataChrome.addJsonHeader?'json':'xml'),false);
            }
        }
	    if (aTopic == "http-on-modify-request") {
              var accept = httpChannel.getRequestHeader("Accept");
	          if (BusinessDataChrome.addJsonHeader){
	            accept = "application/json,"+accept;
	          } else {
	            accept = "application/xml,"+accept;
	          }
	          httpChannel.setRequestHeader("Accept",accept,false);
	          if (accept.indexOf('application/json') != -1 || accept.indexOf('application/xml')!= -1){
	            var dt = new Date();
	            httpChannel.setRequestHeader("Date", dt.toUTCString(), false);
	            if (BusinessDataChrome.addGeneratedContext){
	               httpChannel.setRequestHeader("Context", dt.getTime(), false); 
	            }
	            httpChannel.setRequestHeader("Host", accessInfo.host, false)
	            var signature = BusinessDataChrome.createSignature(accessInfo.secretKey, BusinessDataChrome.createStringToSign(httpChannel,accessInfo, dt));
	            httpChannel.setRequestHeader("Authorization", accessInfo.accessKey+":"+signature, false);
	          }
	      }
	     }
	
	     }
	  }
	}
	
	

let observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
observerService.addObserver(testObserver, "http-on-modify-request", false);
observerService.addObserver(testObserver, "http-on-examine-response", false);
